package cn.jtfadmin.codegen.controller;

import cn.jtfadmin.base.dict.dto.DictItemModelDTO;
import cn.jtfadmin.base.dict.service.DictService;
import cn.jtfadmin.base.dict.service.impl.EnumDictScanConfig;
import cn.jtfadmin.base.lang.common.domain.dto.PageRDTO;
import cn.jtfadmin.base.lang.common.domain.dto.ResultDTO;
import cn.jtfadmin.base.lang.common.domain.dto.SpecConditionDTO;
import cn.jtfadmin.base.lang.common.domain.dto.SpecPagePDTO;
import cn.jtfadmin.base.lang.enums.BooleanEnum;
import cn.jtfadmin.codegen.domain.entity.CodeGenClassEntity;
import cn.jtfadmin.codegen.enums.FieldTypeEnum;
import cn.jtfadmin.codegen.enums.InputTypeEnum;
import cn.jtfadmin.codegen.service.CodeGenClassService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 代码生成Controller
 * @author jtf
 */
@RestController
public class CodeGenClassController {

    @Autowired
    private CodeGenClassService service;

    @Autowired
    private DictService dictService;

    @Autowired
    private EnumDictScanConfig enumDictScanConfig;

    /**
     * 获取实体配置类
     * @param specPagePDTO
     * @return
     */
    @GetMapping(value = "/codegen/entity/list")
    public ResultDTO<PageRDTO<CodeGenClassEntity>> list(SpecPagePDTO<CodeGenClassEntity> specPagePDTO){
        return ResultDTO.successData(service.findAll(specPagePDTO));
    }

    /**
     * 新增
     * @param addPDTO 增增参数
     * @return 无
     */
    @PostMapping(value = "/codegen/entity/add")
    public ResultDTO<String> add(@RequestBody @Validated CodeGenClassEntity addPDTO) {
        return ResultDTO.successData(service.add(addPDTO).getId());
    }

    /**
     * 修改
     * @param editPDTO 修改参数
     * @return 无
     */
    @PutMapping(value = "/codegen/entity/edit")
    public ResultDTO<String> edit(@RequestBody @Validated CodeGenClassEntity editPDTO) {
        return ResultDTO.successData(service.edit(editPDTO).getId());
    }

    /**
     * 按照id删除[[${comment}]]
     * @param id id
     * @return 无
     */
    @DeleteMapping(value = "/codegen/entity/del")
    public ResultDTO<String> del(@RequestParam() @NotBlank String id) {
        service.deleteById(id);
        return ResultDTO.success();
    }

    /**
     * 批量删除[[${comment}]]
     * @param ids id,id,...
     * @return 无
     */
    @DeleteMapping(value = "/codegen/entity/delBatch")
    public ResultDTO<String> delBatch(@RequestParam() @NotBlank String ids) {
        service.deleteBatch(ids);
        return ResultDTO.success();
    }


    /**
     * 按照字段类型获取输入类型
     * @param fieldType
     * @return
     */
    @GetMapping(value = "/codegen/inputType/findByFieldType")
    public ResultDTO<List<DictItemModelDTO>> findInputTypeByFieldType(@RequestParam() @NotNull FieldTypeEnum fieldType){
        List<DictItemModelDTO> dictItemModelByCode = dictService.findDictItemModelByCode(InputTypeEnum.class.getSimpleName());
        Set<String> values = new HashSet<>();
        switch (fieldType){
            case BASIC:{
                values.add(InputTypeEnum.TEXT.name());
                values.add(InputTypeEnum.TEXT_AREA.name());
                values.add(InputTypeEnum.RICH_TEXT.name());
                values.add(InputTypeEnum.BIGDECIMAL.name());
                values.add(InputTypeEnum.NUMBER.name());
                values.add(InputTypeEnum.DATE.name());
                values.add(InputTypeEnum.DATE_TIME.name());
                values.add(InputTypeEnum.TIME.name());
                values.add(InputTypeEnum.File.name());
                break;
            }case ENUM:{
                values.add(InputTypeEnum.RADIO.name());
                values.add(InputTypeEnum.SELECT.name());
                break;
            }case ENTITY:{
                values.add(InputTypeEnum.SELECT.name());
                values.add(InputTypeEnum.RADIO.name());
                break;
            }case COLLECTION:{
                values.add(InputTypeEnum.CHECKBOX.name());
                values.add(InputTypeEnum.SELECT_MU.name());
                break;
            }
        }
        return ResultDTO.successData(dictItemModelByCode.stream()
        .filter(t->values.contains(t.getValue())).collect(Collectors.toList()));
    }

    @GetMapping(value = "/codegen/fieldClass/findFieldsByEntityClass")
    public ResultDTO<List<DictItemModelDTO>> findFieldsByEntityClass(String entity){
        CodeGenClassEntity e = service.findRequiredOneByField("className", entity);
        return ResultDTO.successData(
                e.getFields()
                .stream().filter(t->t.getFieldType().equals(FieldTypeEnum.BASIC) || t.getFieldType().equals(FieldTypeEnum.ENUM))
                .map(t->{
                    return new DictItemModelDTO(t.getName(), t.getName()+"("+t.getComment()+")");
                }).collect(Collectors.toList())
        );
    }

    /**
     * 按照字段类型获取字段Class
     * @param fieldType
     * @return
     */
    @GetMapping(value = "/codegen/fieldClass/findByFieldType")
    public ResultDTO<List<DictItemModelDTO>> findFieldClassByFieldType(@RequestParam() @NotNull FieldTypeEnum fieldType,
                                                                       @RequestParam() @NotNull InputTypeEnum inputType){
        Set<String> values = new HashSet<>();
        switch (fieldType){
            case BASIC:{
                if(inputType.equals(InputTypeEnum.TEXT)
                    ||inputType.equals(InputTypeEnum.TEXT_AREA)
                        ||inputType.equals(InputTypeEnum.RICH_TEXT)
                        ||inputType.equals(InputTypeEnum.File)
                ){
                    values.add(String.class.getName());
                }else if(inputType.equals(InputTypeEnum.BIGDECIMAL)){
                    values.add(BigDecimal.class.getName());
                }else if(inputType.equals(InputTypeEnum.NUMBER)){
                    values.add(Integer.class.getName());
                    values.add(Long.class.getName());
                    values.add(BigInteger.class.getName());
                }
                else if(inputType.equals(InputTypeEnum.DATE)){
                    values.add(LocalDate.class.getName());
                }
                else if(inputType.equals(InputTypeEnum.DATE_TIME)){
                    values.add(LocalDateTime.class.getName());
                }
                else if(inputType.equals(InputTypeEnum.TIME)){
                    values.add(LocalTime.class.getName());
                }
                break;
            }case ENUM:{
                values.addAll(enumDictScanConfig.getEnumClass().stream().map(Class::getName).collect(Collectors.toList()));
                values.add(BooleanEnum.class.getName());
                break;
            }case ENTITY:{

            }case COLLECTION:{
                values.addAll(service.findAll((List<SpecConditionDTO>) null).stream().map(t->t.getClassName()).collect(Collectors.toList()));
                break;
            }
        }
        return ResultDTO.successData(values.stream()
                .map(t->{
                    DictItemModelDTO dto = new DictItemModelDTO(t,t);
                    return dto;
                })
                .collect(Collectors.toList()));
    }

    @PostMapping(value = "/codegen/entity/gen")
    public ResultDTO<String> gen(String id){
        service.doGen(id);
        return ResultDTO.success();
    }


}
